﻿using Aliyun.OSS;
using Aliyun.OSS.Common;
using MT.Common.Helper;
using MT.Component.Abstract.Aliyun;
using MT.Component.Models;
using System;
using System.ComponentModel;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Xbb.Common.Helpers.Abstract;

namespace MT.Component.Concrete.Aliyun
{
    public class FileService:IFileService
    {
        private readonly ITokenHelper _tokenHelper;

        public FileService(ITokenHelper tokenHelper)
        {
            _tokenHelper = tokenHelper;
        }
        public string UrlOOSSign(ImageType imageType, string objectContent = null )
        {
            var client = new OssClient(ConfigHelper.GetSection("Aliyun", "AliyunUrl"), ConfigHelper.GetSection("Aliyun", "AliyunAccessKey"), ConfigHelper.GetSection("Aliyun", "AliyunSecretKey"));
            try
            {
                //UrlSignatureSample
                // 生成上传签名URL。
                var generatePresignedUriRequest = new GeneratePresignedUriRequest(ConfigHelper.GetSection("Aliyun", "BucketName"), _tokenHelper.CreateToken(24), SignHttpMethod.Put)
                {
                    Expiration = DateTime.Now.AddHours(1),
                };
                var signedUrl = client.GeneratePresignedUri(generatePresignedUriRequest);
                // 使用签名URL上传文件。

                PutObjectResult result = null;
                if (!string.IsNullOrEmpty(objectContent))
                {
                    var buffer = Encoding.UTF8.GetBytes(objectContent);
                    using (var ms = new MemoryStream(buffer))
                    {
                        result = client.PutObject(signedUrl, ms);
                    }
                }

                return signedUrl.ToString();

            }
            catch (OssException ex)
            {
                throw ex;
                //return BadRequest(new { Code = ErrorCode.InternalError, Msg = $"Failed with error code: {ex.ErrorCode}; Error info: {ex.Message}. \nRequestID:{ ex.RequestId}\tHostID:{ex.HostId}" });
            }
            catch (Exception ex)
            {
                throw ex;
                //return BadRequest(new { Code = ErrorCode.InternalError, Msg = ex.Message });
            }
        }

        public OOSSignVerify GetOosSignVerify()
        {
            OssClient client = new OssClient($"https://{ConfigHelper.GetSection("Aliyun", "BucketName")}.{ConfigHelper.GetSection("Aliyun", "Endpoint")}", ConfigHelper.GetSection("Aliyun", "AliyunAccessKey"), ConfigHelper.GetSection("Aliyun", "AliyunSecretKey"));
            DateTime now = DateTime.Now;
            DateTime expireTime = now.AddMinutes(30);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.AddConditionItem("content-length-range", 0L, 1048576000L);
            // policyConds.AddConditionItem(MatchMode.StartWith, "key", "mb-");
            // policyConds.AddConditionItem(MatchMode.Exact, "key", "mb-");
            String postPolicy = client.GeneratePostPolicy(expireTime, policyConds);
            byte[] binaryData = Encoding.Default.GetBytes(postPolicy);
            String encodedPolicy = Convert.ToBase64String(binaryData);

            var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(ConfigHelper.GetSection("Aliyun", "AliyunSecretKey")));
            var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(encodedPolicy));
            var Signature = Convert.ToBase64String(hashBytes);

            return new OOSSignVerify() { AccessId = ConfigHelper.GetSection("Aliyun", "AliyunAccessKey"), Dir = ConfigHelper.GetSection("Aliyun", "BucketName"), Expire = expireTime, Host = $"https://{ConfigHelper.GetSection("Aliyun", "BucketName")}.{ConfigHelper.GetSection("Aliyun", "Endpoint")}", Policy = encodedPolicy, Signature = Signature, FileName = _tokenHelper.CreateToken(24) };
        }
    }

    public enum ImageType
    {

        [Description()]
        Goods = 1,
        Head = 2
    }
}
